package com.cskaoyan.javase.array._5operation._4copy;

import java.util.Arrays;

/**
 * 数组的长度是不可以改变的
 * 所以如果想要实现数组元素"真正意义上的"删除和新增，一般需要使用数组的拷贝。
 *
 * 大致思路是，创建一个新数组,然后拷贝赋值：
 *      首先需要明确新数组的长度，初始化这个新数组。
 *      然后遍历原先的数组，过滤掉（或者新增）一些元素，给新数组赋值。
 *
 * @since 17:31
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // int[] _0old = {1, 2, 3};
        // int[] newIntArr = realAddElementInIntArr(_0old, 4);
        // System.out.println(Arrays.toString(newIntArr));

        int[] old = {1, 2, 3, 4, 3, 3, 4, 3, 3};
        int[] newArr = realDeleteElementsInIntArr(old, 3);
        System.out.println(Arrays.toString(newArr));
    }

    // 需求1: 要求在一个int数组的基础上,真正的新增一个元素
    /*
        思考:
            以上需求可以直接在同一个数组上完成吗?
            不可能,数组没有这种操作
            所以如果想要实现数组真正意义上的新增元素,需要使用数组的拷贝
        数组拷贝的原理是:
            1.首先确定新数组的长度,创建新数组
            2.新数组创建完毕后,给新数组中的元素赋值
     */

    /**
     * 使用数组拷贝,真正意义上新增一个元素
     * @param old 原始数组,被新增元素的数组
     * @param target 新增的目标元素
     * @return int[]
     * @author wuguidong@cskaoyan.onaliyun.com
     * @since 2022/05/12 17:35
     */
    public static int[] realAddElementInIntArr(int[] old, int target) {
        // 1.首先确定新数组的长度,创建新数组
        // 新数组的长度 = 老数组的长度 + 1
        int[] result = new int[old.length + 1];
        // 2.新数组创建完毕后,给新数组中的元素赋值
        /*
            如何给新数组赋值呢?
            需要先把老数组中的所有元素都搬过去,然后再把目标元素,赋值进去
            怎么搬老数组中的元素呢?
            遍历老数组,给新数组元素赋值
         */
        /*
            新数组的下标,从0开始,然后每赋值一次,该下标+1
            由于新数组的长度是老数组长度+1,所以这里无需担心数组越界
         */
        int newIndex = 0;
        for (int element : old) {
            result[newIndex] = element;
            newIndex++;
        }
        // 把新增的元素,赋值到新数组的最后一个位置
        result[result.length - 1] = target;
        return result;
    }

    // 需求2: 要求真正意义上的删除int类型数组中的某个元素,但是注意该被删除的元素可能不唯一
    /*
        分析:
        首先肯定不可能在原数组上直接完成
        所以需要使用数组的拷贝:
            1.首先确定新数组的长度,创建新数组
            2.新数组创建完毕后,给新数组中的元素赋值
            (这里的赋值,其实是过滤元素,被删除的元素过滤掉,不进行赋值就可以了)
     */

    /**
     * 过滤掉目标元素,返回新数组
     * @param old 被删除元素的目标数组
     * @param target 被删除的元素,注意目标元素可能不唯一
     * @return int[]
     * @author wuguidong@cskaoyan.onaliyun.com
     * @since 2022/05/12 17:45
     */
    public static int[] realDeleteElementsInIntArr(int[] old, int target) {
        // 1.首先确定新数组的长度,创建新数组
        // 新数组的长度 = 老数组的长度 - 被删除元素的个数
        // 被删除的元素个数如何确定呢? 遍历老数组,然后使用计数器
        int delEleCount = 0;
        for (int ele : old) {
            if (ele == target) {
                delEleCount++;
            }
        }
        // 代码运行到这里,count就是被删除元素的个数
        int[] result = new int[old.length - delEleCount];

        // 2.新数组创建完毕后,给新数组中的元素赋值
        /*
            这里的赋值,其实是过滤元素,被删除的元素过滤掉,不进行赋值就可以了
         */
        // 这里的下标newIndex不用担心越界,因为新数组的长度已经计算好了
        int newIndex = 0;
        for (int ele : old) {
            if (ele == target) {
                // 被删除的元素,需要过滤掉,不能进行赋值
                continue;
            }
            result[newIndex] = ele;
            newIndex++;
        }
        return result;
    }
}
